//! \file rwlock.hpp
//! \brief Purewell Library RWLock Header
//! \author Yubin Lim (purewell@gmail.com)
//! \since 2008-11-10

#ifndef __PWHDR_RWLOCK_HPP__
#define __PWHDR_RWLOCK_HPP__

#include "types.hpp"
#include "lockobject.hpp"

namespace purewell
{

class PWRWLockAttribute;

//! \brief RW-Lock
class PWRWLock : public PWThreadObject
{
public:
	//! \brief Lock type.
	typedef enum _RW_TYPE
	{
		RW_READ = 0,		//!< Read lock.
		RW_WRITE = 1,		//!< Write lock.
		RW_R = RW_READ,		//!< Read lock.
		RW_W = RW_WRITE,	//!< Write lock.
	} LOCK_TYPE;

public:
	//! \brief Lock(wait)
	//! \param[in] type Lock type.
	void lock(int type);

	//! \brief Try to lock(wait).
	//! \return On success, true.
	bool lockTest(int type);

	//! \brief Try to lock(wait) in time.
	//! \param[in] msec Time to wait. Unit is millisecond.
	//! \return On success, true.
	bool lockTimeLimit(int type, size_t msec);

	//! \brief Unlock.
	void unlock(void);

public:
	//! \brief Create RW-Lock.
	//! \param[in] pattr RW-Lock attribution.
	//! \return On success, rw-lock pointer or NULL.
	static PWRWLock* create(const PWRWLockAttribute* pattr = NULL);

	//! \brief Release rw-lock object.
	//! \param[in] lock RW-Lock object pointer.
	static void release(PWRWLock* lock);

private:
	explicit PWRWLock(const PWRWLockAttribute* pattr);
	virtual ~PWRWLock();
};//class PWRWLock

//! \brief RW-Lock Attribution.
class PWRWLockAttribute : public PWThreadObject
{
public:
	//! \brief Create condition attribution.
	//! \return On success pointer of condition attribution, or NULL.
	static PWRWLockAttribute* create(void);

	//! \brief Release condition attribution.
	//! \param[in] obj Condition attribution object to release.
	static void release(PWRWLockAttribute* obj);

private:
	explicit PWRWLockAttribute();
	virtual ~PWRWLockAttribute();
};

};//namespace purewell;

#endif//!__PWHDR_RWLOCK_HPP__

